﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SuperSerialization
{
    class Token
    {
        public static Token EOF = new Token(TokenType.EOF);
        public static Token OPEN_BRACE = new Token(TokenType.OPEN_BRACE);
        public static Token CLOSE_BRACE = new Token(TokenType.CLOSE_BRACE);
        public static Token UNKNOWN = new Token(TokenType.UNKNOWN);
        public static Token ASSIGNMENT = new Token(TokenType.ASSIGNMENT);
        public static Token OPEN_SQUARE = new Token(TokenType.OPEN_SQUARE);
        public static Token CLOSE_SQUARE = new Token(TokenType.CLOSE_SQUARE);
        public static Token SEPARATOR = new Token(TokenType.SEPARATOR);
        public static Token SEMICOLON = new Token(TokenType.SEMICOLON);
        public static Token NAMESPACE = new Token(TokenType.NAMESPACE);
        public static Token MINUS = new Token(TokenType.MINUS);
        public static Token TRUE = new Token(TokenType.TRUE);
        public static Token FALSE = new Token(TokenType.FALSE);
        public static Token NULL = new Token(TokenType.NULL);

        public static Token ErrorToken(string message)
        {
            return new Token(TokenType.ERROR, message);
        }

        private TokenType type;
        public TokenType Type { get { return type; } }
        private string value;
        public string Value { get { return value; } }

        public Token(TokenType type, string value)
        {
            this.type = type;
            this.value = value;
        }

        public Token(TokenType type)
            : this(type, null)
        {

        }

        public override string ToString()
        {
            if (Value == null) return Type.ToString();
            return Type.ToString() + " : \"" + Value + "\"";
        }

        public bool IsLiteral { get { return type == TokenType.STRING || type == TokenType.TRUE || type == TokenType.FALSE || type == TokenType.NULL || IsNumericLiteral; } }

        public bool IsNumericLiteral { get { return type == TokenType.INTEGER || type == TokenType.DOUBLE || type == TokenType.FLOAT; } }
    }

    enum TokenType { ERROR, UNKNOWN, EOF, IDENTIFIER, OPEN_BRACE, CLOSE_BRACE, ASSIGNMENT, STRING, INTEGER, SEPARATOR, OPEN_SQUARE, CLOSE_SQUARE, SEMICOLON, NAMESPACE, MINUS, DOUBLE, FLOAT, TRUE, FALSE, NULL };
}
